﻿/* 
 * Copyright 2010 The Apache Software Foundation.
 *
 * Licensed under the Apache License, Version 2.0 (the "License")
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Reflection;
using log4net;
using Iesi.Collections.Generic;
using Iesi.Collections;

namespace Ngilead.Core
{
    /// <summary>
    /// Clone util class
    /// </summary>
    public class CollectionUtil
    {
        #region Attributes

        /// <summary> Logger channel</summary>
        private static ILog logger = LogManager.GetLogger(typeof(CollectionUtil));

        #endregion

        #region Array

        /// <summary>
        /// Create a new (empty) array of the same type and length as the argument
        /// </summary>
        /// <typeparam name="T">IList</typeparam>
        /// <param name="from">The input array</param>
        /// <returns>The new empty array</returns>
        public static T CreateToArray<T>(T from) where T : IList
        {
            if (logger.IsInfoEnabled)
            {
                logger.Info(String.Format("CreateToArray<T>(T from) : where T is {0}", typeof(T).ToString()));
            }
            try
            {
                ConstructorInfo constructor = from.GetType().GetConstructor(new Type[] { typeof(Int32) });
                return (T)constructor.Invoke(new Object[] { from.Count });
            }
            catch (System.Exception)
            {
                throw new NotSupportedException("Only one dimension array supported...");
            }
        }

        #endregion

        //#region Generic ICollection

        ///// <summary>
        ///// Create a new empty generic collection of the same type as the argument
        ///// </summary>
        ///// <typeparam name="T">Type</typeparam>
        ///// <param name="from">The input collection</param>
        ///// <returns>The new empty generic collection</returns>
        //public static ICollection<T> CreateToGenericICollection<T>(ICollection<T> from) 
        //{
        //    if (logger.IsInfoEnabled)
        //    {
        //        logger.Info(String.Format("CreateToIGenericCollection<T>(ICollection<T> from) : where T is {0}", typeof(T).ToString()));
        //    }
        //    ConstructorInfo constructor = from.GetType().GetConstructor(System.Type.EmptyTypes);
        //    return (ICollection<T>)constructor.Invoke((object[])null);
        //}

        //#endregion

        #region IList

        /// <summary>
        /// Create a new (empty) collection of the same type as the argument
        /// </summary>
        /// <typeparam name="T">IList</typeparam>
        /// <param name="from">The input collection</param>
        /// <returns>The new empty collection</returns>
        public static T CreateToIList<T>(T from) where T : IList
        {
            if (logger.IsInfoEnabled)
            {
                logger.Info(String.Format("CreateToCollection<T>(T from) : where T is {0}", typeof(T).ToString()));
            }
            ConstructorInfo constructor = from.GetType().GetConstructor(System.Type.EmptyTypes);
            return (T)constructor.Invoke((object[])null);
        }

        /// <summary>
        /// Create a new (empty) collection of the same type as the argument
        /// </summary>
        /// <typeparam name="T">ISet</typeparam>
        /// <param name="from">The input collection</param>
        /// <returns>The new empty collection</returns>
        public static T CreateToSet<T>(T from) where T : ISet
        {
            if (logger.IsInfoEnabled)
            {
                logger.Info(String.Format("CreateToCollection<T>(T from) : where T is {0}", typeof(T).ToString()));
            }
            ConstructorInfo constructor = from.GetType().GetConstructor(System.Type.EmptyTypes);
            return (T)constructor.Invoke((object[])null);
        }

        #endregion

        #region IDictionary

        /// <summary>
        /// Create a new (empty) dictionary of the same type as the argument
        /// </summary>
        /// <typeparam name="T">IDictionary</typeparam>
        /// <param name="from">The input dictionary</param>
        /// <returns>The new empty dictionary</returns>
        public static T CreateToDictionary<T>(T from) where T : IDictionary
        {
            if (logger.IsInfoEnabled)
            {
                logger.Info(String.Format("CreateToDictionary<T>(T from) : where T is {0}", typeof(T).ToString()));
            }
            ConstructorInfo constructor = from.GetType().GetConstructor(System.Type.EmptyTypes);
            return (T)constructor.Invoke((object[])null);
        }

        #endregion
    }
}
